Skip to content

Conversation

@sebpop
Copy link
Contributor

@sebpop sebpop commented Nov 20, 2025

This is to be committed on top of #167698

@sebpop sebpop requested a review from kasuga-fj November 20, 2025 22:28
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Nov 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Sebastian Pop (sebpop)

Changes

This is to be committed on top of #167698


Patch is 49.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/168963.diff

6 Files Affected:

  • (modified) llvm/include/llvm/Analysis/DependenceAnalysis.h (+6-184)
  • (modified) llvm/lib/Analysis/DependenceAnalysis.cpp (+28-574)
  • (modified) llvm/test/Analysis/DependenceAnalysis/Propagating.ll (+1-1)
  • (modified) llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll (+1-1)
  • (modified) llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll (+2-2)
  • (modified) llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll (+2-2)
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 85c9af4fffcde..2e845104464a5 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -365,48 +365,6 @@ class DependenceInfo {
   depends(Instruction *Src, Instruction *Dst,
           bool UnderRuntimeAssumptions = false);
 
-  /// getSplitIteration - Give a dependence that's splittable at some
-  /// particular level, return the iteration that should be used to split
-  /// the loop.
-  ///
-  /// Generally, the dependence analyzer will be used to build
-  /// a dependence graph for a function (basically a map from instructions
-  /// to dependences). Looking for cycles in the graph shows us loops
-  /// that cannot be trivially vectorized/parallelized.
-  ///
-  /// We can try to improve the situation by examining all the dependences
-  /// that make up the cycle, looking for ones we can break.
-  /// Sometimes, peeling the first or last iteration of a loop will break
-  /// dependences, and there are flags for those possibilities.
-  /// Sometimes, splitting a loop at some other iteration will do the trick,
-  /// and we've got a flag for that case. Rather than waste the space to
-  /// record the exact iteration (since we rarely know), we provide
-  /// a method that calculates the iteration. It's a drag that it must work
-  /// from scratch, but wonderful in that it's possible.
-  ///
-  /// Here's an example:
-  ///
-  ///    for (i = 0; i < 10; i++)
-  ///        A[i] = ...
-  ///        ... = A[11 - i]
-  ///
-  /// There's a loop-carried flow dependence from the store to the load,
-  /// found by the weak-crossing SIV test. The dependence will have a flag,
-  /// indicating that the dependence can be broken by splitting the loop.
-  /// Calling getSplitIteration will return 5.
-  /// Splitting the loop breaks the dependence, like so:
-  ///
-  ///    for (i = 0; i <= 5; i++)
-  ///        A[i] = ...
-  ///        ... = A[11 - i]
-  ///    for (i = 6; i < 10; i++)
-  ///        A[i] = ...
-  ///        ... = A[11 - i]
-  ///
-  /// breaks the dependence and allows us to vectorize/parallelize
-  /// both loops.
-  LLVM_ABI const SCEV *getSplitIteration(const Dependence &Dep, unsigned Level);
-
   Function *getFunction() const { return F; }
 
   /// getRuntimeAssumptions - Returns all the runtime assumptions under which
@@ -447,106 +405,6 @@ class DependenceInfo {
     unsigned char DirSet;
   };
 
-  /// Constraint - This private class represents a constraint, as defined
-  /// in the paper
-  ///
-  ///           Practical Dependence Testing
-  ///           Goff, Kennedy, Tseng
-  ///           PLDI 1991
-  ///
-  /// There are 5 kinds of constraint, in a hierarchy.
-  ///   1) Any - indicates no constraint, any dependence is possible.
-  ///   2) Line - A line ax + by = c, where a, b, and c are parameters,
-  ///             representing the dependence equation.
-  ///   3) Distance - The value d of the dependence distance;
-  ///   4) Point - A point <x, y> representing the dependence from
-  ///              iteration x to iteration y.
-  ///   5) Empty - No dependence is possible.
-  class Constraint {
-  private:
-    enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
-    ScalarEvolution *SE;
-    const SCEV *A;
-    const SCEV *B;
-    const SCEV *C;
-    const Loop *AssociatedSrcLoop;
-    const Loop *AssociatedDstLoop;
-
-  public:
-    /// isEmpty - Return true if the constraint is of kind Empty.
-    bool isEmpty() const { return Kind == Empty; }
-
-    /// isPoint - Return true if the constraint is of kind Point.
-    bool isPoint() const { return Kind == Point; }
-
-    /// isDistance - Return true if the constraint is of kind Distance.
-    bool isDistance() const { return Kind == Distance; }
-
-    /// isLine - Return true if the constraint is of kind Line.
-    /// Since Distance's can also be represented as Lines, we also return
-    /// true if the constraint is of kind Distance.
-    bool isLine() const { return Kind == Line || Kind == Distance; }
-
-    /// isAny - Return true if the constraint is of kind Any;
-    bool isAny() const { return Kind == Any; }
-
-    /// getX - If constraint is a point <X, Y>, returns X.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getX() const;
-
-    /// getY - If constraint is a point <X, Y>, returns Y.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getY() const;
-
-    /// getA - If constraint is a line AX + BY = C, returns A.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getA() const;
-
-    /// getB - If constraint is a line AX + BY = C, returns B.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getB() const;
-
-    /// getC - If constraint is a line AX + BY = C, returns C.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getC() const;
-
-    /// getD - If constraint is a distance, returns D.
-    /// Otherwise assert.
-    LLVM_ABI const SCEV *getD() const;
-
-    /// getAssociatedSrcLoop - Returns the source loop associated with this
-    /// constraint.
-    LLVM_ABI const Loop *getAssociatedSrcLoop() const;
-
-    /// getAssociatedDstLoop - Returns the destination loop associated with
-    /// this constraint.
-    LLVM_ABI const Loop *getAssociatedDstLoop() const;
-
-    /// setPoint - Change a constraint to Point.
-    LLVM_ABI void setPoint(const SCEV *X, const SCEV *Y,
-                           const Loop *CurrentSrcLoop,
-                           const Loop *CurrentDstLoop);
-
-    /// setLine - Change a constraint to Line.
-    LLVM_ABI void setLine(const SCEV *A, const SCEV *B, const SCEV *C,
-                          const Loop *CurrentSrcLoop,
-                          const Loop *CurrentDstLoop);
-
-    /// setDistance - Change a constraint to Distance.
-    LLVM_ABI void setDistance(const SCEV *D, const Loop *CurrentSrcLoop,
-                              const Loop *CurrentDstLoop);
-
-    /// setEmpty - Change a constraint to Empty.
-    LLVM_ABI void setEmpty();
-
-    /// setAny - Change a constraint to Any.
-    LLVM_ABI void setAny(ScalarEvolution *SE);
-
-    /// dump - For debugging purposes. Dumps the constraint
-    /// out to OS.
-    LLVM_ABI void dump(raw_ostream &OS) const;
-  };
-
   /// Returns true if two loops have the Same iteration Space and Depth. To be
   /// more specific, two loops have SameSD if they are in the same nesting
   /// depth and have the same backedge count. SameSD stands for Same iteration
@@ -713,8 +571,7 @@ class DependenceInfo {
   /// If the dependence isn't proven to exist,
   /// marks the Result as inconsistent.
   bool testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
-               FullDependence &Result, Constraint &NewConstraint,
-               const SCEV *&SplitIter) const;
+               FullDependence &Result) const;
 
   /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
   /// Things of the form [c1 + a1*i] and [c2 + a2*j]
@@ -744,7 +601,7 @@ class DependenceInfo {
   bool strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
                      const SCEV *DstConst, const Loop *CurrentSrcLoop,
                      const Loop *CurrentDstLoop, unsigned Level,
-                     FullDependence &Result, Constraint &NewConstraint) const;
+                     FullDependence &Result) const;
 
   /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
   /// (Src and Dst) for dependence.
@@ -759,8 +616,7 @@ class DependenceInfo {
   bool weakCrossingSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
                            const SCEV *DstConst, const Loop *CurrentSrcLoop,
                            const Loop *CurrentDstLoop, unsigned Level,
-                           FullDependence &Result, Constraint &NewConstraint,
-                           const SCEV *&SplitIter) const;
+                           FullDependence &Result) const;
 
   /// ExactSIVtest - Tests the SIV subscript pair
   /// (Src and Dst) for dependence.
@@ -774,8 +630,7 @@ class DependenceInfo {
   bool exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
                     const SCEV *SrcConst, const SCEV *DstConst,
                     const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
-                    unsigned Level, FullDependence &Result,
-                    Constraint &NewConstraint) const;
+                    unsigned Level, FullDependence &Result) const;
 
   /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
   /// (Src and Dst) for dependence.
@@ -790,8 +645,7 @@ class DependenceInfo {
   bool weakZeroSrcSIVtest(const SCEV *DstCoeff, const SCEV *SrcConst,
                           const SCEV *DstConst, const Loop *CurrentSrcLoop,
                           const Loop *CurrentDstLoop, unsigned Level,
-                          FullDependence &Result,
-                          Constraint &NewConstraint) const;
+                          FullDependence &Result) const;
 
   /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
   /// (Src and Dst) for dependence.
@@ -806,8 +660,7 @@ class DependenceInfo {
   bool weakZeroDstSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
                           const SCEV *DstConst, const Loop *CurrentSrcLoop,
                           const Loop *CurrentDstLoop, unsigned Level,
-                          FullDependence &Result,
-                          Constraint &NewConstraint) const;
+                          FullDependence &Result) const;
 
   /// exactRDIVtest - Tests the RDIV subscript pair for dependence.
   /// Things of the form [c1 + a*i] and [c2 + b*j],
@@ -927,37 +780,6 @@ class DependenceInfo {
   void findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B, BoundInfo *Bound,
                     unsigned K) const;
 
-  /// intersectConstraints - Updates X with the intersection
-  /// of the Constraints X and Y. Returns true if X has changed.
-  bool intersectConstraints(Constraint *X, const Constraint *Y);
-
-  /// findCoefficient - Given a linear SCEV,
-  /// return the coefficient corresponding to specified loop.
-  /// If there isn't one, return the SCEV constant 0.
-  /// For example, given a*i + b*j + c*k, returning the coefficient
-  /// corresponding to the j loop would yield b.
-  const SCEV *findCoefficient(const SCEV *Expr, const Loop *TargetLoop) const;
-
-  /// zeroCoefficient - Given a linear SCEV,
-  /// return the SCEV given by zeroing out the coefficient
-  /// corresponding to the specified loop.
-  /// For example, given a*i + b*j + c*k, zeroing the coefficient
-  /// corresponding to the j loop would yield a*i + c*k.
-  const SCEV *zeroCoefficient(const SCEV *Expr, const Loop *TargetLoop) const;
-
-  /// addToCoefficient - Given a linear SCEV Expr,
-  /// return the SCEV given by adding some Value to the
-  /// coefficient corresponding to the specified TargetLoop.
-  /// For example, given a*i + b*j + c*k, adding 1 to the coefficient
-  /// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
-  const SCEV *addToCoefficient(const SCEV *Expr, const Loop *TargetLoop,
-                               const SCEV *Value) const;
-
-  /// updateDirection - Update direction vector entry
-  /// based on the current constraint.
-  void updateDirection(Dependence::DVEntry &Level,
-                       const Constraint &CurConstraint) const;
-
   /// Given a linear access function, tries to recover subscripts
   /// for each dimension of the array element access.
   bool tryDelinearize(Instruction *Src, Instruction *Dst,
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index ea261820fb2e6..940cedea33def 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -18,11 +18,6 @@
 // of memory references in a function, returning either NULL, for no dependence,
 // or a more-or-less detailed description of the dependence between them.
 //
-// Currently, the implementation cannot propagate constraints between
-// coupled RDIV subscripts and lacks a multi-subscript MIV test.
-// Both of these are conservative weaknesses;
-// that is, not a source of correctness problems.
-//
 // Since Clang linearizes some array subscripts, the dependence
 // analysis is using SCEV->delinearize to recover the representation of multiple
 // subscripts, and thus avoid the more expensive and less precise MIV tests. The
@@ -92,8 +87,6 @@ STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
 STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
 STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
 STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
-STATISTIC(DeltaApplications, "Delta applications");
-STATISTIC(DeltaSuccesses, "Delta successes");
 STATISTIC(GCDapplications, "GCD applications");
 STATISTIC(GCDsuccesses, "GCD successes");
 STATISTIC(GCDindependence, "GCD independence");
@@ -445,7 +438,6 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
             for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
               if (D->isSplitable(Level)) {
                 OS << "  da analyze - split level = " << Level;
-                OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
                 OS << "!\n";
               }
             }
@@ -625,282 +617,6 @@ bool FullDependence::inSameSDLoops(unsigned Level) const {
   return Level > Levels;
 }
 
-//===----------------------------------------------------------------------===//
-// DependenceInfo::Constraint methods
-
-// If constraint is a point <X, Y>, returns X.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getX() const {
-  assert(Kind == Point && "Kind should be Point");
-  return A;
-}
-
-// If constraint is a point <X, Y>, returns Y.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getY() const {
-  assert(Kind == Point && "Kind should be Point");
-  return B;
-}
-
-// If constraint is a line AX + BY = C, returns A.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getA() const {
-  assert((Kind == Line || Kind == Distance) &&
-         "Kind should be Line (or Distance)");
-  return A;
-}
-
-// If constraint is a line AX + BY = C, returns B.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getB() const {
-  assert((Kind == Line || Kind == Distance) &&
-         "Kind should be Line (or Distance)");
-  return B;
-}
-
-// If constraint is a line AX + BY = C, returns C.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getC() const {
-  assert((Kind == Line || Kind == Distance) &&
-         "Kind should be Line (or Distance)");
-  return C;
-}
-
-// If constraint is a distance, returns D.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getD() const {
-  assert(Kind == Distance && "Kind should be Distance");
-  return SE->getNegativeSCEV(C);
-}
-
-// Returns the source loop associated with this constraint.
-const Loop *DependenceInfo::Constraint::getAssociatedSrcLoop() const {
-  assert((Kind == Distance || Kind == Line || Kind == Point) &&
-         "Kind should be Distance, Line, or Point");
-  return AssociatedSrcLoop;
-}
-
-// Returns the destination loop associated with this constraint.
-const Loop *DependenceInfo::Constraint::getAssociatedDstLoop() const {
-  assert((Kind == Distance || Kind == Line || Kind == Point) &&
-         "Kind should be Distance, Line, or Point");
-  return AssociatedDstLoop;
-}
-
-void DependenceInfo::Constraint::setPoint(const SCEV *X, const SCEV *Y,
-                                          const Loop *CurSrcLoop,
-                                          const Loop *CurDstLoop) {
-  Kind = Point;
-  A = X;
-  B = Y;
-  AssociatedSrcLoop = CurSrcLoop;
-  AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setLine(const SCEV *AA, const SCEV *BB,
-                                         const SCEV *CC, const Loop *CurSrcLoop,
-                                         const Loop *CurDstLoop) {
-  Kind = Line;
-  A = AA;
-  B = BB;
-  C = CC;
-  AssociatedSrcLoop = CurSrcLoop;
-  AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setDistance(const SCEV *D,
-                                             const Loop *CurSrcLoop,
-                                             const Loop *CurDstLoop) {
-  Kind = Distance;
-  A = SE->getOne(D->getType());
-  B = SE->getNegativeSCEV(A);
-  C = SE->getNegativeSCEV(D);
-  AssociatedSrcLoop = CurSrcLoop;
-  AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setEmpty() { Kind = Empty; }
-
-void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
-  SE = NewSE;
-  Kind = Any;
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-// For debugging purposes. Dumps the constraint out to OS.
-LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS) const {
-  if (isEmpty())
-    OS << " Empty\n";
-  else if (isAny())
-    OS << " Any\n";
-  else if (isPoint())
-    OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
-  else if (isDistance())
-    OS << " Distance is " << *getD() << " (" << *getA() << "*X + " << *getB()
-       << "*Y = " << *getC() << ")\n";
-  else if (isLine())
-    OS << " Line is " << *getA() << "*X + " << *getB() << "*Y = " << *getC()
-       << "\n";
-  else
-    llvm_unreachable("unknown constraint type in Constraint::dump");
-}
-#endif
-
-// Updates X with the intersection
-// of the Constraints X and Y. Returns true if X has changed.
-// Corresponds to Figure 4 from the paper
-//
-//            Practical Dependence Testing
-//            Goff, Kennedy, Tseng
-//            PLDI 1991
-bool DependenceInfo::intersectConstraints(Constraint *X, const Constraint *Y) {
-  ++DeltaApplications;
-  LLVM_DEBUG(dbgs() << "\tintersect constraints\n");
-  LLVM_DEBUG(dbgs() << "\t    X ="; X->dump(dbgs()));
-  LLVM_DEBUG(dbgs() << "\t    Y ="; Y->dump(dbgs()));
-  assert(!Y->isPoint() && "Y must not be a Point");
-  if (X->isAny()) {
-    if (Y->isAny())
-      return false;
-    *X = *Y;
-    return true;
-  }
-  if (X->isEmpty())
-    return false;
-  if (Y->isEmpty()) {
-    X->setEmpty();
-    return true;
-  }
-
-  if (X->isDistance() && Y->isDistance()) {
-    LLVM_DEBUG(dbgs() << "\t    intersect 2 distances\n");
-    if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
-      return false;
-    if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
-      X->setEmpty();
-      ++DeltaSuccesses;
-      return true;
-    }
-    // Hmmm, interesting situation.
-    // I guess if either is constant, keep it and ignore the other.
-    if (isa<SCEVConstant>(Y->getD())) {
-      *X = *Y;
-      return true;
-    }
-    return false;
-  }
-
-  // At this point, the pseudo-code in Figure 4 of the paper
-  // checks if (X->isPoint() && Y->isPoint()).
-  // This case can't occur in our implementation,
-  // since a Point can only arise as the result of intersecting
-  // two Line constraints, and the right-hand value, Y, is never
-  // the result of an intersection.
-  assert(!(X->isPoint() && Y->isPoint()) &&
-         "We shouldn't ever see X->isPoint() && Y->isPoint()");
-
-  if (X->isLine() && Y->isLine()) {
-    LLVM_DEBUG(dbgs() << "\t    intersect 2 lines\n");
-    const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
-    const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
-    if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
-      // slopes are equal, so lines are parallel
-      LLVM_DEBUG(dbgs() << "\t\tsame slope\n");
-      Prod1 = SE->getMulExpr(X->getC(), Y->getB());
-      Prod2 = SE->getMulExpr(X->getB(), Y->getC());
-      if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
-        return false;
-      if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
-        X->setEmpty();
-        ++DeltaSuccesses;
-        return true;
-      }
-      return false;
-    }
-    if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
-      // slopes differ, so lines intersect
-      LLVM_DEBUG(dbgs() << "\t\tdifferent slopes\n");
-      const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
-      const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
-      const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
-      const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->g...
[truncated]

@github-actions
Copy link

github-actions bot commented Nov 20, 2025

🐧 Linux x64 Test Results

  • 186456 tests passed
  • 4864 tests skipped

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test still necessary?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are better to keep, as they help a lot with testing future changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but maybe the file should be renamed, as "Propagation" is completely removed.

Copy link
Contributor

@kasuga-fj kasuga-fj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sebpop sebpop force-pushed the da-remove-constraints branch from 936700e to b055afe Compare November 21, 2025 17:13
@sebpop sebpop merged commit ad9bc6a into llvm:main Nov 21, 2025
10 checks passed
@sebpop sebpop deleted the da-remove-constraints branch November 21, 2025 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:analysis Includes value tracking, cost tables and constant folding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants